package com.wwinsoft.framework.web.workflow;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.beans.factory.annotation.Autowired;

import com.google.common.collect.Maps;
import com.wwinsoft.framework.entity.security.User;
import com.wwinsoft.framework.pojo.workflow.TaskBean;
import com.wwinsoft.framework.service.workflow.TaskQueryService;
import com.wwinsoft.framework.utils.JXLTHelper;
import com.wwinsoft.framework.web.SimpleActionSupport;
import com.wwinsoft.modules.orm.Page;
import com.wwinsoft.modules.security.springsecurity.SpringSecurityUtils;
import com.wwinsoft.modules.utils.PropertiesUtils;
import com.wwinsoft.modules.utils.web.struts2.Struts2Utils;

/**
 * @author: Tim Chen
 * @since 1.0
 */
@Namespace("/workflow")
@Results({ @Result(name = SimpleActionSupport.RELOAD, location = "task!inbox.action", type = "redirect") })
public class TaskAction extends SimpleActionSupport {

    @Autowired
    private TaskService taskService;

    @Autowired
    private TaskQueryService taskQueryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private FormService formService;

    private Page<? extends Task> page = new Page<Task>();

    private String taskId;

    private TaskBean filter = new TaskBean();

    private static final String TASK_EXCEL_TEMPLATE = "/template/excel/Task_Template.xls";

    public Page<? extends Task> getPage() {
        return page;
    }

    public String inbox() throws Exception {
        String username = SpringSecurityUtils.getCurrentUser().getUsername();
        filter.setAssignee(username);
        Map paraMap = PropertiesUtils.toParameterMap(filter);
        page = taskQueryService.searchTaskPage(page, paraMap);
        return "tasks";
    }

    public void inboxExp()throws Exception {
        String username = SpringSecurityUtils.getCurrentUser().getUsername();
        filter.setAssignee(username);
        Map paraMap = PropertiesUtils.toParameterMap(filter);
        List<? extends Task> tasks = taskQueryService.searchTaskList(paraMap);
         exportExcel(tasks);
    }

    public String queued() throws Exception {
        String username = SpringSecurityUtils.getCurrentUser().getUsername();
        filter.setCandidateUser(username);
        Map paraMap = PropertiesUtils.toParameterMap(filter);
        paraMap.put("isNotAssigneed",true);
        page = taskQueryService.searchTaskPage(page, paraMap);
        return "queuedTasks";
    }

    public void queuedExp()throws Exception {
        String username = SpringSecurityUtils.getCurrentUser().getUsername();
        filter.setCandidateUser(username);
        Map paraMap = PropertiesUtils.toParameterMap(filter);
        paraMap.put("isNotAssigneed",true);
         exportExcel(taskQueryService.searchTaskList(paraMap));
    }


    public String all() throws Exception {
        String username = SpringSecurityUtils.getCurrentUser().getUsername();
        filter.setCandidateUser(username);
        Map paraMap = PropertiesUtils.toParameterMap(filter);
        page = taskQueryService.searchTaskPage(page, paraMap);
        return "allTasks";
    }

    public void allExp()throws Exception {
        String username = SpringSecurityUtils.getCurrentUser().getUsername();
        filter.setCandidateUser(username);
        Map paraMap = PropertiesUtils.toParameterMap(filter);
         exportExcel(taskQueryService.searchTaskList(paraMap));
    }

    private void exportExcel(List<? extends Task> tasks) {
        Map<String, Object> beans = new HashMap<String, Object>();
        beans.put("dataList", tasks);
        String fileName = "任务列表";
        JXLTHelper.writeXLTtoResponse(beans, TASK_EXCEL_TEMPLATE, fileName);
    }


    public String claim() throws Exception {
        if (StringUtils.isNotEmpty(taskId)) {
            String username = SpringSecurityUtils.getCurrentUser().getUsername();
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            if (task.getAssignee() != null) {
                addErrorMessage("该任务已经被别人领取!");
                return RELOAD;
            }
            taskService.claim(taskId, username);
        }
        return RELOAD;
    }

    public String assign() throws Exception{
        String assignee = Struts2Utils.getParameter("assignee");
        if(StringUtils.isNotEmpty(taskId) && StringUtils.isNotEmpty(assignee)){
            taskService.setAssignee(taskId,assignee);
            addActionMessage("任务分配成功!");
        } else {
             addErrorMessage("任务分配失败!");
        }
        return pageManualSelect();
    }
    
    public String pageManualSelect() throws Exception{
        String targetPage = Struts2Utils.getParameter("targetPage");
        if (StringUtils.isEmpty(targetPage)){
            return queued();
        }

        if("all".equals(targetPage)){
            return all();
        } else  if("queued".equals(targetPage)){
            return  queued();
        }

         return queued();
    }

    public void getTaskCandidateUsers(){
        String taskId = Struts2Utils.getParameter("taskId");
        Map<String,Object> paraMap = Maps.newHashMap();
        paraMap.put("taskId", taskId);
        List<User> users = taskQueryService.selectTaskCandidateUsers(paraMap);
        Struts2Utils.renderJson(users);
    }

    public String getFormKey(String taskId) {
        if (StringUtils.isEmpty(taskId)) {
            return null;
        }
        return formService.getTaskFormData(taskId).getFormKey();
    }

    public String getProcessName(String processDefinitionId) {
        return repositoryService.createProcessDefinitionQuery().processDefinitionId(
                processDefinitionId).singleResult().getName();
    }

    public String getInitiator(String processInstanceId) {
        return getVariable(processInstanceId, "initiator") ;
    }

    public String getSubject(String processInstanceId) {
        return getVariable(processInstanceId, "subject") ;
    }

    private String getVariable(String processInstanceId, String variableName) {
        Object variable = runtimeService.getVariable(processInstanceId, variableName);
        if(variable!=null){
            return  String.valueOf(variable);
        }
        return "";
    }

    private int firstResult() {
        return page.getFirst() - 1;
    }

    private int maxResults() {
        return page.getPageSize();
    }

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public TaskBean getFilter() {
        return filter;
    }
}
